home *** CD-ROM | disk | FTP | other *** search
Wrap
var widgetIsShowing = true, widgetAtFront = true; var top_monitor=2, mid_monitor=0, bot_monitor=1; //setting initial conditions corresponding with the list below (changed if widget preferences set) var num_procs = 1; //this is for seph at macthemesforums ;) /* cpu = 0 ram = 1 network = 2 battery = 3 airport = 4 basically, we print these out from the shell script in the order they appear in the HTML, making life a bit easier to figure out which monitor to use for the values... */ var cli_monitors = ['c','r','n','b','a','d']; var monitors = ['CPU Usage','RAM Usage','Network Load','Battery Level','Airport Strength','Startup Disk Usage']; function getSysInfo() { if (window.widget && widgetIsShowing && widgetAtFront) { //we set up the command line arguments to send the shell script: var cli_args = "-" + cli_monitors[top_monitor] + cli_monitors[mid_monitor] + cli_monitors[bot_monitor]; var sys_info = widget.system("sysinfo.sh " + cli_args, null).outputString.split(","); //100 - (/(\d+)([\t\w]*)$/img.exec(sar)[0])*1; //alert('from script: ' + sys_info); var top_light_value = Math.abs(Math.round(sys_info[top_monitor]*1)); //incase of a weird RAM thingy with dual procs... (should probs just do it in the shell script, tbh) var lcd_value = Math.abs(Math.round(sys_info[mid_monitor]*1)); var big_light_value = Math.abs(Math.round(sys_info[bot_monitor]*1)); //don't know which monitor is cpu, so... if (top_monitor == 0) top_light_value = Math.round(top_light_value/num_procs); if (mid_monitor == 0) lcd_value = Math.round(lcd_value/num_procs); if (bot_monitor == 0) big_light_value = Math.round(big_light_value/num_procs); //alert('tl: ' + top_light_value + ", lcd: " + lcd_value + ", big: " + big_light_value); var lcd_info = document.getElementById("lcd_info"); var top_light_imgs = document.getElementById("top_light").getElementsByTagName("img"); var big_light_imgs = document.getElementById("big_light").getElementsByTagName("img"); document.getElementById("top_light").setAttribute("title", monitors[top_monitor] + ": " + top_light_value); lcd_info.setAttribute("title", monitors[mid_monitor] + ": " + lcd_value); document.getElementById("big_light").setAttribute("title", monitors[bot_monitor] + ": " + big_light_value + "%"); //lcd first: if (lcd_value < 100) { lcd_info.style.fontSize = "30px"; lcd_info.style.top = "60px"; lcd_info.style.left = "50px"; } else { lcd_info.style.fontSize = "23px"; lcd_info.style.top = "63px"; lcd_info.style.left = "47px"; } lcd_info.innerText = lcd_value; document.getElementById("lcd_crisis").style.visibility = (lcd_value < 80) ? "hidden" : "visible"; //now the top light: if (monitors[top_monitor] == "Airport Strength" || monitors[top_monitor] == "Battery Level") top_light_value = 100 - (top_light_value*1); //since the higher the better for these... var top_light_vals = getOpacities(top_light_value*1); top_light_imgs[0].style.opacity = top_light_vals[0]; top_light_imgs[1].style.opacity = top_light_vals[1]; top_light_imgs[2].style.opacity = top_light_vals[2]; //and finally the big light: if (monitors[bot_monitor] == "Airport Strength" || monitors[bot_monitor] == "Battery Level") big_light_value = 100 - (big_light_value*1); //since the higher the better for these... var big_light_vals = getOpacities(big_light_value*1); big_light_imgs[0].style.opacity = big_light_vals[0]; big_light_imgs[1].style.opacity = big_light_vals[1]; big_light_imgs[2].style.opacity = big_light_vals[2]; setTimeout("getSysInfo()", 2000); //update every two seconds } } function getOpacities(perc) { //rather shoddy way of doing this, tbh: var g, y, r; if (perc <= 20) { g = 1.0; y = 0.0; r = 0.0; } else if (perc > 20 && perc <= 50) { g = 1- ((perc - 20)/30); y = (perc - 20)/30; r = 0.0; } else if (perc > 50 && perc <= 80) { g = 0.0; y = 1- ((perc - 50)/30); r = (perc - 50)/30; } else { g = 0.0; y = 0.0; r = 1.0; } //alert("g: " + g + ", y: " + y + ", r: " + r); var ar = [g, y, r]; return ar; } function togglePreferences() { var f = document.getElementById("front"); var b = document.getElementById("back"); if (b.style.display != "block") { widgetAtFront = false; document.getElementById("shutter").style.display = "block"; //meh, this is fugly, but necessary: info_anim.play('forward', function() { b.style.display = "block"; f.style.display = "none"; if (window.widget) { widget.prepareForTransition("ToBack"); setTimeout("widget.performTransition()", 0); } setTimeout( function(){ if (Statosphere) { if (Statosphere.isRegistered()) { document.getElementById("not_registered").style.display = "none"; document.getElementById("registered").style.display = "block"; } else { document.getElementById("not_registered").style.display = "block"; document.getElementById("registered").style.display = "none"; } } pref_anim.play('forward', function() { fade("preferences", 0, 1, null); widget.setCloseBoxOffset(25,25); }); }, 1000); }); } else { //and this looks even worse :/ fade("preferences", 1, 0, function() { pref_anim.play('back', function() { b.style.display = "none"; f.style.display = "block"; if (window.widget) { widget.prepareForTransition("ToFront"); setTimeout("widget.performTransition()", 0); } setTimeout(function(){info_anim.play('back', function() { document.getElementById("shutter").style.display = "none"; widgetAtFront = true; getSysInfo(); widget.setCloseBoxOffset(25,155); });}, 1000); }); }); } } function doneSettings() { if (window.widget) { //alert("----------------------------------") //set prefs var pref_imgs = document.getElementById("preferences").getElementsByTagName("img"); for (var i=0; i < pref_imgs.length-1; i++) { if (pref_imgs[i].style.display != "none") { widget.setPreferenceForKey(pref_imgs[i].offsetTop, pref_imgs[i].id + "_top"); widget.setPreferenceForKey(pref_imgs[i].offsetLeft, pref_imgs[i].id + "_left"); widget.setPreferenceForKey(pref_imgs[i].getAttribute("docked"), pref_imgs[i].id + "_docked"); //alert(pref_imgs[i].id + " : " + pref_imgs[i].getAttribute("docked")); } } } togglePreferences(); } //mouseover stuff for the 'i' button: var isShown = false; function mouseOver(e) { document.getElementById("flipper").style.visibility = "visible"; e.cancelBubble = true; if (e.target.parentNode.id == "flip" && !isShown) { fade('flip_back', 0, 0.3, null); isShown = true; } } function mouseOut(e) { document.getElementById("flipper").style.visibility = "hidden"; e.cancelBubble = true; if (e.target.id != "flipper" && e.target.parentNode.id != "flip" && isShown) { if (document.getElementById("flip").style.display != "none") { fade('flip_back', 0.3, 0, null); } else { document.getElementById("flip_back").style.opacity = 0.0; document.getElementById("flip").style.display = ""; } isShown = false; } } function fade(el, from, to, callBack) { //so we can pass a string for the id or an element: if (el == new String(el)) el = document.getElementById(el); var dif = Math.abs(to - from); var pi = Math.PI; var i = 0; //to gain a slight speed boost - work out all values first. var opacs = []; for (var theta=0; theta < 90; theta+=8) { //play with the increment value for theta to get this smoother if (to > from) var step = Math.sin((theta*pi)/180); else var step = Math.cos((theta*pi)/180); opacs.push(dif*step); } var inter = setInterval( function() { if (++i < opacs.length) { el.style.opacity = Math.max(0.01, opacs[i]); //fixing safari glitch } else { el.style.opacity = to; clearInterval(inter); if (callBack != null) callBack(); } }, 100); //play with this interval value to get this smoother } function slideTo(el, from_x, from_y, to_x, to_y, speed, callBack) { if (el == new String(el)) el = document.getElementById(el); var x_dif = (to_x - from_x)/10; var y_dif = (to_y - from_y)/10; var theta = 0; var inter = setInterval( function() { if (theta < 10) { theta++; from_x += x_dif; from_y += y_dif; el.style.left = from_x + "px"; el.style.top = from_y + "px"; } else { el.style.left = to_x + "px"; el.style.top = to_y + "px"; clearInterval(inter); if (callBack != null) callBack(); } }, speed); } function Animation(id, what, strip_width, loops, interval) { this.inter = null; this.instance = id; //i suppose this could possibly be done using random numbers instead, but... eval(this.instance + " = this"); //giving us a reference to the object - I don't like eval in general, but this is an easy way of getting round this problem this.element = document.getElementById(what); this.left = 0; this.cur_loop = 0; this.dx = this.element.offsetWidth + 10; this.strip_width = strip_width; this.loops = loops; this.interval = interval; this.isPlaying = false; this.end_point = 0; this.dir = "forward"; this.callBack = null; this.play = function(dir, callBack) { if (!this.isPlaying) { this.isPlaying = true; this.dir = dir; this.callBack = callBack; if (this.dir == "back") { this.end_point = this.strip_width * -1; this.left = 10; } else { this.end_point = 0; this.left = this.strip_width; } //alert('dx: ' + this.dx); this.inter = setInterval(this.instance + ".roll()", this.interval); } } this.stop = function () { clearInterval(this.inter); this.isPlaying = false; } this.roll = function() { this.left -= this.dx; //document.getElementById("debug").innerHTML += this.left + "<br />"; if (this.left >= this.end_point) { var pos = (this.dir == "back") ? this.left * -1 : this.left; this.element.style.backgroundPosition = pos + "px 0"; } else { if (this.loops > 0 && ++this.cur_loop >= this.loops) { clearInterval(this.inter); this.cur_loop = 0; this.isPlaying = false; if (this.callBack != null) { this.callBack(); this.callBack = null; } } else { this.element.style.backgroundPosition = "0 0"; } } } } /* OK. Since there's only ever going to be one thing dragged at a time, we can make use of a global variable to keep track of the current object being dragged and also add the event listener to the body so we can drag it all over without having problems if the object doesn't follow the mouse fast enough... */ var cur_drag_obj = null; function DraggableElement(what, id, controller, endFunction) { this.element = (what == new String(what)) ? document.getElementById(what) : what; this.instance = id; eval(this.instance + " = this"); this.controller = controller; this.endFunction = endFunction; this.canmove = false; this.init_y = 0; this.init_x = 0; this.init_top = 0; this.init_left = 0; this.mousemove = function(e) { if (this.canmove) { this.top = e.clientY - this.init_y; this.left = e.clientX - this.init_x; //so, controller is actually the controlling function. This //means we can use this 'class' for multiple things, //such as scrollbars or sliders etc. if (this.controller != null) this.controller(); } } this.mousedown = function(e) { this.element.style.zIndex = 99; this.init_top = this.element.offsetTop; this.init_left = this.element.offsetLeft; this.init_y = (e.clientY - this.init_top); this.init_x = (e.clientX - this.init_left); this.canmove = true; //the following seems rather 'hacky' doesn't it? cur_drag_obj = this; document.body.addEventListener("mousemove", dragging, false); document.body.addEventListener("mouseup", finishDragging, false); } this.mouseup = function(e) { this.element.style.zIndex = 1; this.canmove = false; if (this.endFunction != null) this.endFunction(); //and remove the event listeners: document.body.removeEventListener("mousemove", dragging, false); document.body.removeEventListener("mouseup", finishDragging, false); } this.element.setAttribute("onmousedown", this.instance + ".mousedown(event)"); } /* note that I had to actually make these to as proper functions for the event listeners, otherwise they weren't being removed (when using something like function(e){cur_drag_obj.mousemove(e);} instead). */ function dragging(e) { cur_drag_obj.mousemove(e); } function finishDragging(e) { cur_drag_obj.mouseup(e); } /* I seriously need to give the following function a bit more thought :/ */ function dockElement(el, where) { var docked, node; //now make them dock at the pref points: if (this.left >= 36 && this.left <= 55) { if (this.top >= 11 && this.top <= 21) { this.top = 15; this.left = 42; docked = "top"; } else if (this.top >= 38 && this.top <= 55) { this.top = 44; this.left = 42; docked = "middle"; } else if (this.top >= 65 && this.top <= 79) { this.top = 71; this.left = 42; docked = "bottom"; } } else { docked = "no"; //this is temporary until i decide whether there *has* to be something in all of the three slots } //run down the images on the back and undock ones that are docked where we want to be: //we'll also get what node we are, to add it to the pos_monitor vars var pref_imgs = document.getElementById("preferences").getElementsByTagName("img"); for (var i=0; i < pref_imgs.length-1; i++) { if (pref_imgs[i] != this.element && pref_imgs[i].offsetTop == this.top && pref_imgs[i].offsetLeft == this.left) { var swapped_dock = this.element.getAttribute("docked") pref_imgs[i].setAttribute("docked", swapped_dock); switch (swapped_dock) { case "top": top_monitor = i; break; case "middle": mid_monitor = i; break; case "bottom": bot_monitor = i; break; } //pref_imgs[i].style.top = this.init_top + "px"; //pref_imgs[i].style.left = this.init_left + "px"; slideTo(pref_imgs[i], this.left, this.top, this.init_left, this.init_top, 10, null); //break; } if (pref_imgs[i] == this.element) node = i; } switch (docked) { case "top": top_monitor = node; break; case "middle": mid_monitor = node; break; case "bottom": bot_monitor = node; break; } this.element.style.top = this.top + "px"; this.element.style.left = this.left + "px"; //and now set our elements docked attribute to reflect it's new place: this.element.setAttribute("docked", docked); //alert("top: " + top_monitor + ", mid: " + mid_monitor + ", bot: " + bot_monitor); } dockElement.prototype = DraggableElement; function moveElement() { //keep them within the bounds of the prefs area: if (this.top <= 0) this.top = 0; if (this.top >= 95) this.top = 95; if (this.left <= 0) this.left = 0; if (this.left >= 81) this.left = 81; this.element.style.top = this.top + "px"; this.element.style.left = this.left + "px"; } moveElement.prototype = DraggableElement; function toggleRunning(e) { if (e.altKey) { widgetIsShowing = !widgetIsShowing; } } function getOffsetTop(element) { var top = 0; var el = element; do { top += el.offsetTop; el = el.parentNode; } while (el !== document.body); return top; } function getOffsetLeft(element) { var left = 0; var el = element; do { left += el.offsetLeft; el = el.parentNode; } while (el !== document.body); return left; } var help_running = false; function showHelp() { //this is basically an animation showing how to use the widget: help_running = true; //get a non docked element and the element docked at the top: var top_docked, non_docked; var pref_imgs = document.getElementById("preferences").getElementsByTagName("img"); for (var i=0; i < pref_imgs.length-2; i++) { //taking into account the done button if (pref_imgs[i].getAttribute("docked") == "top") top_docked = pref_imgs[i]; if (pref_imgs[i].getAttribute("docked") == "no") non_docked = pref_imgs[i]; } //HAHA - the following is almost a joke, isn't it? document.getElementById("cover").style.display = "block"; showHelpText(0, function () { circleObject(non_docked, function () { hideHelpText(0, function () { circleObject(top_docked, function () { var l = non_docked.offsetLeft; var t = non_docked.offsetTop; slideTo(non_docked, l, t, 42, 15, 100, function () { slideTo(top_docked, 42, 15, l, t, 100, function () { showHelpText(1, function () { circleObject('done_preferences', function () { hideHelpText(1, function () { showHelpText(2, function () { setTimeout( function() { hideHelpText(2, function () { fade("help_circle_canvas", 1.0, 0, function() {document.getElementById("help_circle_canvas").style.opacity = 1.0; document.getElementById("help_circle_canvas").style.display = "none";}); togglePreferences(); setTimeout( function() { //put the moved items on the back back to where they were: slideTo(top_docked, l, t, 42, 15, 100, null); slideTo(non_docked, 42, 15, l, t, 100, null); document.getElementById("help_text").style.top = "170px"; circleObject('top_light', function () { showHelpText(3, function () { setTimeout( function() { hideHelpText(3, function () { showHelpText(4, function () { setTimeout( function() { hideHelpText(4, function () { showHelpText(5, function () { setTimeout( function() { hideHelpText(5, function () { document.getElementById("help_circle_canvas").style.display = "none"; document.getElementById("cover").style.display = "none"; document.getElementById("help_text").style.top = "100px"; togglePreferences(); }); //hideHelpText 5 }, 3000); });//showHelpText 5 });//hideHelpText 4 }, 3000); });//showHelpText 4 });//hideHelpText 3 }, 3000); });//howHelpText 3 });//circleObject 'top_light' }, 3500); });//hideHelpText 2 }, 3000); });//showHelpText 2 });//hideHelpText 1 });//circleObject 'done_preferences' });//showHelpText 1 });//slideTo });//slideTo });//circleObject top_docked });//hideHelpText 0 });//circleObject non_docked });//showHelpText 0 } function cancelHelp() { help_running = false; document.getElementById("help_circle_canvas").style.display = "none"; document.getElementById("help_text").style.display = "none"; document.getElementById("cover").style.display = "none"; document.getElementById("help_text").style.top = "100px"; } function handleKeyPress(e) { if (e.charCode == 27 && help_running) cancelHelp(); } function circleObject(obj, callBack) { if (!help_running) return false; if (obj == new String(obj)) obj = document.getElementById(obj); var help_canvas = document.getElementById("help_circle_canvas"); var help_context = help_canvas.getContext("2d"); help_canvas.style.display = "block"; help_canvas.style.top = (getOffsetTop(obj) - 5) + "px"; help_canvas.style.left = (getOffsetLeft(obj) - 5) + "px"; //help_canvas.setAttribute("height", 200); //help_canvas.setAttribute("width", 200); /*help_canvas.setAttribute("height", obj.offsetHeight + 20); help_canvas.setAttribute("width", obj.offsetWidth + 20); */ help_context.lineWidth = 3; help_context.strokeStyle = "rgba(255, 0, 0, 0.8)"; help_context.clearRect(0, 0, 50, 50); help_context.save(); help_context.scale(1.3, 1); help_context.beginPath(); help_context.moveTo(5, 10); var i=0; var inter = setInterval( function () { //alert(i); switch (i) { case 0: help_context.bezierCurveTo(5, 0, 20, 10, 20, 20); break; case 1: help_context.beginPath(); help_context.moveTo(20, 10); help_context.bezierCurveTo(30, 20, 20, 30, 15, 20); break; case 2: help_context.beginPath(); help_context.moveTo(20, 30); help_context.bezierCurveTo(10, 35, 5, 25, 5, 10); break; case 3: help_context.beginPath(); help_context.moveTo(5, 25); help_context.bezierCurveTo(2, 7, 9, 10, 0, 0); break; //Default: case 4: clearInterval(inter); help_context.restore(); if (callBack != null) callBack(); break; } help_context.stroke(); i++; }, 70); } function showHelpText(which, callBack) { if (!help_running) return false; var help_text = document.getElementById("help_text"); help_text.style.display = "block"; var messages = help_text.getElementsByTagName("div"); if (which > 0) messages[which-1].style.opacity = 0; fade(messages[which], 0, 0.9, function() { //setTimeout("help_text_shadow.paint()", 100); callBack(); }); } function hideHelpText(which, callBack) { var help_text = document.getElementById("help_text"); var messages = help_text.getElementsByTagName("div"); //if (which > 0) messages[which-1].style.opacity = 0; fade(messages[which], 0.9, 0, function () { help_text.style.display = "none"; callBack(); }); } function ShadowedElement(what) { this.element = (what == new String(what)) ? document.getElementById(what) : what; //add in shadow: this.canvas_container = document.createElement("div"); this.canvas_container.className = "shadow_container"; this.element.insertBefore(this.canvas_container, this.element.firstChild); this.canvas = document.createElement("canvas"); this.canvas.setAttribute("height", this.canvas_container.offsetHeight); //seems it doesn't scale 100% to the actual width of it - the width/height is extended by padding, y'see this.canvas.setAttribute("width", this.canvas_container.offsetWidth); this.canvas_container.appendChild(this.canvas); this.context = this.canvas.getContext("2d"); this.paint = function() { //alert('painting shadow'); this.context.shadowBlur = 7; this.context.shadowOffsetX = 0; this.context.shadowOffsetY = 3; this.context.lineWidth = 10; this.context.beginPath(); this.context.strokeRect(14, 14, this.element.offsetWidth-10, this.element.offsetHeight-10); } this.paint(); } var help_running_order = []; //animation objects: var pref_anim; //opening and closing of the preferences var info_anim; //the circle on the front opening and closing //var help_text_shadow; function register() { if (Statosphere) Statosphere.registerWidget(); } function buy() { if (Statosphere) Statosphere.buyWidget(); } function init() { if (window.widget) { window.resizeTo(139, 291); widget.setCloseBoxOffset(25,155); //get preferences: //check to see if they have a battery (they're using an [i|power]Book): var has_battery = widget.preferenceForKey("has_battery"); if (!has_battery) { //not false, but undefined //this is the first run of the widget, so check what type of mac it is: var model = widget.system("/usr/sbin/sysctl hw.model", null).outputString; has_battery = (model.indexOf("PowerBook") != -1) ? "true" : "false"; widget.setPreferenceForKey(has_battery, "has_battery"); } if (has_battery == "false") document.getElementById("battery").style.display = "none"; //and now see if they have an airport card: } //set up the flip ('i') button: var bod = document.getElementsByTagName("body")[0]; bod.addEventListener("mouseover", mouseOver, false); bod.addEventListener("mouseout", mouseOut, false); document.getElementById("flip").addEventListener("mouseup", function(e){document.getElementById("flip").style.display="none"; togglePreferences();}, false); //set up animation objects: pref_anim = new Animation('pref_anim', 'back', 2970, 1, 10); info_anim = new Animation('info_anim', 'shutter', 1286, 1, 10); /* and set up the preference elements to be able to move: since we make our own reference to the object instance in the object it doesn't matter what variables we use here (go local vars! hehe) */ var pref_imgs = document.getElementById("preferences").getElementsByTagName("img"); for (var i=0; i < pref_imgs.length-2; i++) { //taking into account the done button and help button if (pref_imgs[i].style.display != "none") { if (window.widget) { var top = widget.preferenceForKey(pref_imgs[i].id + "_top"); var left = widget.preferenceForKey(pref_imgs[i].id + "_left"); pref_imgs[i].style.top = top + "px"; pref_imgs[i].style.left = left + "px"; var docked = widget.preferenceForKey(pref_imgs[i].id + "_docked"); //alert(pref_imgs[i].id + "'s docked: " + docked); if (docked) { pref_imgs[i].setAttribute("docked", docked); if (docked == "top") top_monitor = i; //pref_imgs[i].id; if (docked == "middle") mid_monitor = i; //pref_imgs[i].id; if (docked == "bottom") bot_monitor = i; //pref_imgs[i].id; } } var tmp = new DraggableElement(pref_imgs[i], "move_"+i, moveElement, dockElement); } } //now change the back to have no display: document.getElementById("back").style.display = "none"; document.getElementById("back").style.visibility = "visible"; //doing it this way to stop any flickering (well, attempt to anyway). document.getElementById("front").style["background"] = "url(images/ball.png) no-repeat"; info_anim.play('back', function(){ document.getElementById("shutter").style.display = "none"; document.getElementsByTagName("body")[0].addEventListener("click", toggleRunning, true); if (window.widget) { //make sure our script is executable: widget.system("/bin/chmod 777 sysinfo.sh", null); //and the aiport prog: widget.system("/bin/chmod 777 airport", null); //figure out how many processors they have: num_procs = parseInt(widget.system("/usr/sbin/sysctl -n hw.ncpu", null).outputString); setTimeout("getSysInfo()", 500); } }); //help_text_shadow = new ShadowedElement('help_text') document.addEventListener("keydown", handleKeyPress, false); } window.onload = init; if (window.widget) { widget.onhide = function(){widgetIsShowing = false;}; widget.onshow = function(){widgetIsShowing = true; getSysInfo();}; }